﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RgbColor.cs" company="Marcelo Roca">
//   Copyright (c) 2011 Marcelo Roca. All rights reserved.
// </copyright>
// <author name="Marcelo Roca" email="marce@marceloroca.com"/>
// <license>
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
// 
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program.  If not, see http://www.gnu.org/licenses/.
// </license>
// --------------------------------------------------------------------------------------------------------------------

namespace GameKits.Unity.GuiForms
{
    using UnityEngine;

    public struct RgbColor
    {
        /// <summary>
        /// El valor del rojo
        /// </summary>
        private float r;

        /// <summary>
        /// El valor del verde
        /// </summary>
        private float g;

        /// <summary>
        /// El valor del azul
        /// </summary>
        private float b;

        /// <summary>
        /// Initializes a new instance of the <see cref="RgbColor"/> struct.
        /// </summary>
        /// <param name="r">
        /// The red value.
        /// </param>
        /// <param name="g">
        /// The green value.
        /// </param>
        /// <param name="b">
        /// The blue value.
        /// </param>
        public RgbColor(float r, float g, float b)
        {
            this.r = Mathf.Clamp01(r);
            this.g = Mathf.Clamp01(g);
            this.b = Mathf.Clamp01(b);
        }

        /// <summary>
        /// Gets or sets Red value.
        /// </summary>
        public float R
        {
            get { return this.r; }
            set { this.r = Mathf.Clamp01(value); }
        }

        /// <summary>
        /// Gets or sets Green value.
        /// </summary>
        public float G
        {
            get { return this.g; }
            set { this.g = Mathf.Clamp01(value); }
        }

        /// <summary>
        /// Gets or sets Blue value.
        /// </summary>
        public float B
        {
            get { return this.b; }
            set { this.b = Mathf.Clamp01(value); }
        }

        /// <summary>
        /// Compara dos elementos RgbColor
        /// </summary>
        /// <param name="a">
        /// El objeto a.
        /// </param>
        /// <param name="b">
        /// El objeto b.
        /// </param>
        /// <returns>
        /// True si son el mismo valor
        /// </returns>
        public static bool operator ==(RgbColor a, RgbColor b)
        {
            return a.R == b.R && a.G == b.G && a.B == b.B;
        }

        /// <summary>
        /// Compara dos elementos RgbColor
        /// </summary>
        /// <param name="a">
        /// El objeto a.
        /// </param>
        /// <param name="b">
        /// El objeto b.
        /// </param>
        /// <returns>
        /// True si son diferentes
        /// </returns>
        public static bool operator !=(RgbColor a, RgbColor b)
        {
            return !(a == b);
        }

        /// <summary>
        /// Obtiene si es igual el objeto a este
        /// </summary>
        /// <param name="other">
        /// El objeto a comparar.
        /// </param>
        /// <returns>
        /// True si son iguales
        /// </returns>
        public bool Equals(RgbColor other)
        {
            return other.r.Equals(this.r) && other.g.Equals(this.g) && other.b.Equals(this.b);
        }

        /// <summary>
        /// Obtiene si es ingual un objeto a este
        /// </summary>
        /// <param name="obj">
        /// El objeto a comparar.
        /// </param>
        /// <returns>
        /// True si son iguales
        /// </returns>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }

            if (obj.GetType() != typeof(RgbColor))
            {
                return false;
            }

            return this.Equals((RgbColor)obj);
        }

        /// <summary>
        /// Obtiene el hascode del control
        /// </summary>
        /// <returns>
        /// El hashcode
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var result = this.r.GetHashCode();
                result = (result * 397) ^ this.g.GetHashCode();
                result = (result * 397) ^ this.b.GetHashCode();
                return result;
            }
        }

        /// <summary>
        /// Convierte el valor a uno del tipo unity
        /// </summary>
        /// <param name="r">
        /// El color r a multiplicar.
        /// </param>
        /// <param name="g">
        /// El color g a multiplicar.
        /// </param>
        /// <param name="b">
        /// El color b a multiplicar.
        /// </param>
        /// <param name="alpha">
        /// The alpha.
        /// </param>
        /// <returns>
        /// El color correspondiente en Unity
        /// </returns>
        public Color ToColor(float r, float g, float b, float alpha)
        {
            return new Color(this.r * r, this.g * g, this.b * b, alpha);
        }

        /// <summary>
        /// Convierte el valor a uno del tipo unity
        /// </summary>
        /// <param name="alpha">
        /// The alpha.
        /// </param>
        /// <returns>
        /// El color correspondiente en Unity
        /// </returns>
        public Color ToColor(float alpha)
        {
            return new Color(this.r, this.g, this.b, alpha);
        }

        /// <summary>
        ///  Convierte el valor a uno del tipo unity
        /// </summary>
        /// <returns>
        /// El color correspondiente en Unity
        /// </returns>
        public Color ToColor()
        {
            return new Color(this.r, this.g, this.b, 1);
        }       
    }
}
